﻿namespace GreenIsomer.Web.Controls.JQuery {
	using System;
	using System.ComponentModel;
	using System.ComponentModel.Design.Serialization;
	using System.Globalization;
	using System.Reflection;
	using System.Collections;

	/// <summary>
	/// Provides conversions for the GreenIsomer.Web.Controls.JQuery.Grid struct.
	/// </summary>
	public class GridConverter : TypeConverter {


		#region Constructors

		/// <summary>
		/// Initializes a new GreenIsomer.Web.Controls.JQuery.GridConverter class.
		/// </summary>
		public GridConverter() { }

		#endregion


		#region Methods: Capabilities

		/// <summary>
		/// Returns whether this converter can convert an object of the given type to the type of this converter, using the specified context.
		/// </summary>
		/// <param name="context">A System.ComponentModel.ITypeDescriptorContext that provides a format context.</param>
		/// <param name="sourceType">The type of the object to be converted.</param>
		/// <returns>Whether or not the conversion can be performed.</returns>
		public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType) {
			if(sourceType == typeof(string)) return true;
			return base.CanConvertFrom(context, sourceType);
		}

		/// <summary>
		/// Returns whether this converter can convert the object to the specified type, using the specified context.
		/// </summary>
		/// <param name="context">A System.ComponentModel.ITypeDescriptorContext that provides a format context.</param>
		/// <param name="destinationType">The target type of the object.</param>
		/// <returns>Whether or not the conversion can be performed.</returns>
		public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType) {
			if(destinationType == typeof(string)) return true;
			if(destinationType == typeof(InstanceDescriptor)) return true;
			return base.CanConvertTo(context, destinationType);
		}

		#endregion


		#region Methods: Perform tasks

		/// <summary>
		/// Converts the given object to the type of this converter, using the specified context and culture information.
		/// </summary>
		/// <param name="context">A System.ComponentModel.ITypeDescriptorContext that provides a format context.</param>
		/// <param name="culture">The System.Globalization.CultureInfo to use as the current culture.</param>
		/// <param name="value">The object to be converted</param>
		/// <returns>The converted object.</returns>
		public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value) {
			if(value == null)
				return new Grid();

			string text = value as string;
			if(text != null) {
				if(text.Length == 0)
					return new Grid();

				int intValue;
				if(int.TryParse(text, out intValue))
					return new Grid(intValue);

				string[] splitText = text.Split(',');
				if(splitText.Length == 2) {
					int x; int y;
					if(int.TryParse(splitText[0], out x) && int.TryParse(splitText[1], out y))
						return new Grid(x, y);
				}
			}

			return base.ConvertFrom(context, culture, value);
		}

		/// <summary>
		/// Converts the given object value to the specified type, using the specified context and culture information.
		/// </summary>
		/// <param name="context">A System.ComponentModel.ITypeDescriptorContext that provides a format context.</param>
		/// <param name="culture">The System.Globalization.CultureInfo to use as the current culture.</param>
		/// <param name="value">The object to be converted</param>
		/// <param name="destinationType">The System.Type to convert the value parameter to.</param>
		/// <returns>The converted object.</returns>
		public override object ConvertTo(ITypeDescriptorContext context, CultureInfo culture, object value, Type destinationType) {

			if(destinationType == typeof(string))
				return ((Grid)value).ToString();

			if(destinationType == typeof(InstanceDescriptor)) {
				Grid grid = (Grid)value;

				if(!grid.IsSet) return new InstanceDescriptor(
					typeof(Grid).GetField("None", BindingFlags.Public | BindingFlags.Static),
					null, true);

				if(grid.IsSquare) return new InstanceDescriptor(
					typeof(Grid).GetConstructor(new Type[] { typeof(int) }),
					new object[] { grid.X });

				return new InstanceDescriptor(
					typeof(Grid).GetConstructor(new Type[] { typeof(int), typeof(int) }),
					new object[] { grid.X, grid.Y });
			}

			return base.ConvertTo(context, culture, value, destinationType);
		}

		#endregion


	}

}